#include "Room.h"
#include "Reservation.h"

Room::Room(ifstream & file, int roomNum) : Num_element(roomNum) {
	reservations = new List(Sorted);
	roomNumber   = &number;

	/* Read COMMON room data */

	// Read number of reservations
	int numReservations = 0;
	file >> numReservations;		file.ignore();

	// Read all reservations
	for (unsigned i = 0; i < numReservations; i++) {
		int arrivalDate = 0;
		file >> arrivalDate;		file.ignore();

		Reservation *res = new Reservation(file, arrivalDate);

		/* Reservations which are over-due are ignored,
		 * as specified in "forutsetninger.txt".
		 */
		if (res->departureDate >= Singletons::currentDate) {
			reservations->add(res);
		}
		
		res->room = this;
	}

	// Read bed count
	file >> bedCount;				file.ignore();

	// Read breakfast included
	file >> breakfastIncluded;		file.ignore();
}

Room::Room(int rNum) : Num_element(rNum) {
	roomNumber = &rNum;
	reservations = new List(Sorted);
}

Room::~Room(void) {
	delete reservations;
}

void Room::WriteToFile(ofstream &file) {
	file << *roomNumber;
	file << endl;
	
	file << reservations->no_of_elements();
	file << endl;
	
	// Going over all reservations and write them to file
	for (unsigned i = 0; i < reservations->no_of_elements(); i++) {
		Reservation *res = (Reservation*)reservations->remove_no(i+1);
		reservations->add(res);
		
		res->WriteToFile(file);
	}
	
	file << bedCount;
	file << endl;
	
	file << breakfastIncluded;
	file << endl;
}

void Room::display() {
	printf("\n\tRoom number: %i\n", *roomNumber);

	if( getBedCount() == 1) {
		printf("\n\tThere is 1 bed");
	}
	else {
		printf("\n\tThere are %i beds", getBedCount());
	}

	if(breakfastIncluded) {
		printf("\n\tThere is breakfast included");
	} else {
		printf("\n\tThere is no beakfast included");
	}
}

int Room::getBedCount() {
	return bedCount;
}

Room::RoomType Room::GetType() {
	return roomType;
}

int Room::getRoomNumber() {
	return *roomNumber;
}


bool Room::AvailableAtDate(Date d) {

	// Going through all reservations and check if it is avalible
	for (unsigned i = 0; i < reservations->no_of_elements(); i++) {
		Reservation *res = (Reservation*)reservations->remove_no(i+1);
		reservations->add(res);
		
		if (res->IncludesDate(d)) {
			return false;
		}
	}
	
	return true;
}

bool Room::AvailableInPeriod(Date from, Date to) {

	// Going through the days and check if it is avalible
	for (Date d = from; d <= to; d = Singletons::timer->nestedato(d)) {
		if (!AvailableAtDate(d)) {
			return false;
		}
	}
	return true;
}

Reservation* Room::getCurrentReservation() {
	Date date = Singletons::currentDate;
	
	// Going through all reservations and check if there is an reservation
	for (unsigned i = 0; i < reservations->no_of_elements(); i++) {
		Reservation *res = (Reservation*)reservations->remove_no(i+1);
		reservations->add(res);
		
		if ((date >= res->arrivalDate)   &&
			(date <= res->departureDate) &&
			res->isCheckedIn()) {
			return res;
		}
	}
	
	return NULL;
}

void Room::addReservation(Reservation *toAdd) {
	reservations->add(toAdd);
	toAdd->room = this;
}

void Room::removeReservation(Reservation *toRemove) {
	for (unsigned i = 0; i < reservations->no_of_elements(); i++) {
		Reservation *res = (Reservation*)reservations->remove_no(i+1);

		/* If "res == toRemove", it will not be re-added */
		if (res != toRemove) {
			reservations->add(res);
		}
	}
}